import numpy as np
import pandas as pd
from pyecharts.charts import Pie, Timeline
# from pyecharts.globals import ThemeType
from pyecharts import options as opts
import random
import re

class Doughnut_and_RoseDiagram_weather_timeline(): #圆环图
    
    def __init__(self,dataset, place=0):
        self.paint_data=dataset
        self.place=place #九寨沟——0；四姑娘山——1
        self.weather=[];
        
        #主程序入口
        self.main()
    
    #主程序入口函数实现
    def main(self):
        
        # 调用获取数据函数
        self.getData()
        # 调用圆环图绘制函数
        self.paintDoughnut()
        # 调用玫瑰图绘制函数
        self.paintRoseDiagram()
        
    #获取数据
    def getData(self):
            
        df=self.paint_data.loc[:,['date','weather']] #提取日期数据和天气数据
        df.columns = ['date','weather'] #表头名称

        df['date'] = pd.to_datetime(df['date']) #将数据类型转换为日期类型
        self.paint_data = df.set_index('date') # 将date设置为index       

    #减少多余天气种类
    def clean(self,data_tuple_list):
        for i in range(len(data_tuple_list)):
            newline=re.split('转|~', data_tuple_list[i][0])
            data_tuple_list[i]=(newline[0],data_tuple_list[i][1])

        dic={}
        for item in data_tuple_list:
            if dic.get(item[0]) is None:
                dic[item[0]]=0
            dic[item[0]]=dic.get(item[0])+item[1]
        # 绘制圆环图
        data_tuple_list = [(k, v) for k, v in dic.items()]
        return data_tuple_list


    #绘制圆环图
    def paintDoughnut(self):
        
        if self.place==0:
            place='九寨沟'
            years=range(2013, 2017) #设置年份范围
            fileName="2.2 九寨沟2013-2016年天气数据统计圆环图（含时间轴）.html"
        else:
            place='小金'
            years=range(2016, 2020) #设置年份范围
            fileName="2.2 小金2016-2019年天气数据统计圆环图（含时间轴）.html"
        

        
        tl = Timeline()
        for i in years:
            year=str(i)
            # print(year)
            weather=self.paint_data[year] #筛选某一年的天气数据               
            # print(weather)
            
            #统计数组中相同元素的数量
            def all_np(arr):
                arr = np.array(arr) #将数据转化为np数组
                key = np.unique(arr)
                result = {}
                for k in key:
                    mask = (arr == k)
                    arr_new = arr[mask]
                    v = arr_new.size
                    result[k] = v
                return result
            
            weather_nums=all_np(weather) #共有xx种天气
            data=sorted(weather_nums.items(), key=lambda item:item[1]) #将字典按values从高到低进行排序，生成的是list     
            # print(data)  
            data=self.clean(data) #清洗天气数据，合并出现次数少的天气
            # data=sorted(data, key=lambda x:x[1]) #重新进行排序
            
            # print(data)
            # 绘制圆环图
            c=(
                # Pie(init_opts=opts.InitOpts(theme=ThemeType.DARK, width="900px", height="600px"))
                Pie(init_opts=opts.InitOpts(width="900px", height="600px"))
                .add(series_name=place+" {} 年天气数据统计".format(i), data_pair=data, 
                # 饼图的半径，数组的第一项是内半径，第二项是外半径，默认设置成百分比
                radius=["50%","70%"])
                .set_colors([
                             "LightPink","DeepPink","Crimson","LavenderBlush","PaleVioletRed",
                             "HotPink","DeepPink","MediumVioletRed","Orchid",'Thistle','Plum',
                             'Violet','Magenta','Fuchsia','DarkMagenta','Purple','MediumOrchid',
                             'DarkViolet','DarkOrchid','Indigo','BlueViolet',
                             'MediumPurple','MediumSlateBlue','SlateBlue','DarkSlateBlue','Lavender'])
                .set_global_opts(title_opts=opts.TitleOpts(title=place+" {} 年天气数据统计".format(i),pos_left="left"),
                                 legend_opts=opts.LegendOpts(is_show=False))
                .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)"))
            )
            tl.add(c, "{}年".format(i))
        tl.render('resultFile/'+fileName)
        
        print(fileName+"已生成！")


    # 绘制玫瑰图
    def paintRoseDiagram(self):
        
        if self.place==0:
            place='九寨沟'
            years=range(2013, 2017) #设置年份范围
            fileName="2.1 九寨沟2013-2016年天气数据统计玫瑰图（含时间轴）.html"
        else:
            place='小金'
            years=range(2016, 2020) #设置年份范围
            fileName="2.1 小金2016-2019年天气数据统计玫瑰图（含时间轴）.html"
        
        # 随机颜色生成
        def randomcolor(kind):
            colors = []
            for i in range(kind):
                colArr = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
                color = ""
                for i in range(6):
                    color += colArr[random.randint(0, 14)]
                colors.append("#" + color)
            return colors               
        
        tl = Timeline()
        for i in years:
            df=self.paint_data[str(i)] #筛选某一年的天气数据               
            weather=df
            
            #统计数组中相同元素的数量
            def all_np(arr):
                arr = np.array(arr) #将数据转化为np数组
                key = np.unique(arr)
                result = {}
                for k in key:
                    mask = (arr == k)
                    arr_new = arr[mask]
                    v = arr_new.size
                    result[k] = v
                return result
            
            weather_nums=all_np(weather) #共有xx种天气
            data=sorted(weather_nums.items(), key=lambda item:item[1]) #将字典按values从高到低进行排序，生成的是list
        
            data=self.clean(data) #清洗天气数据，合并出现次数少的天气
            
            category=dict(data)# 将list转化为字典
            
            #将字典拆分成keys和values两部分
            keys = tuple(category.keys())
            weather=list(keys)
            values = tuple(category.values())
            num=list(values)
            
            color_series = randomcolor(len(num))
            
            # 创建饼图
            fig = Pie(init_opts=opts.InitOpts(width='900px', height='600px'))
            # 添加数据
            fig.add("", [list(z) for z in zip(weather, num)],
                    radius=['30%', '135%'],
                    center=['50%', '65%'],
                    rosetype='area')
            
            # 设置全局配置
            fig.set_global_opts(title_opts=opts.TitleOpts(title=place+" {} 年天气数据统计".format(i)),
                                legend_opts=opts.LegendOpts(is_show=False)
                                )
            
            # 设置系列配置和颜色
            fig.set_series_opts(label_opts=opts.LabelOpts(is_show=True, position='inside', font_size=12,
                                                          formatter='{b}:{c}天', font_style='italic', font_weight='bold',
                                                          font_family='Microsoft YaHei')) # b:province;c:num
            fig.set_colors(color_series)
            tl.add(fig, "{}年".format(i))
        
        # 在网页生成照片
        tl.render('resultFile/'+fileName)
        
        print(fileName+'已生成！')
